#ifndef SYMBOLTABLENODE_H
#define SYMBOLTABLENODE_H

#include "SymbolTableNode.h"
#include <iostream>
#include <string>
#include <vector>
#include <map>

#define INTEGER_SIZE 4
#define REAL_SIZE 8
#define BOOLEAN_SIZE 1
#define CHAR_SIZE 2

#define INTEGER 1
#define REAL 2
#define BOOLEAN 3
#define CHAR 4
#define ARRAY 5
#define FUNCTION 6
#define PROCEDURE 7

class SymbolTable
{
public:
    SymbolTable();
    void insert(string name, SymbolTableNode symbol);
    void getInfo();
    bool find(string name);

private:
    map<string, SymbolTableNode> Table;
    int Loc;
};

SymbolTable::SymbolTable()
{
    Loc = 0;
}

void SymbolTable::insert(string name, SymbolTableNode symbol)
{
    symbol.Memloc = Loc;
    if (Table.find(name) == Table.end())
    {
        if (symbol.Type[0] == INTEGER)
            Loc += INTEGER_SIZE;
        else if (symbol.Type[0] == REAL)
            Loc += REAL_SIZE;
        else if (symbol.Type[0] == BOOLEAN)
            Loc += BOOLEAN_SIZE;
        else if (symbol.Type[0] == CHAR)
            Loc += CHAR_SIZE;
        else if (symbol.Type[0] == ARRAY)
        {
            int len = 0;
            if (symbol.Type[1] == INTEGER)
                len += INTEGER_SIZE;
            else if (symbol.Type[1] == REAL)
                len += REAL_SIZE;
            else if (symbol.Type[1] == BOOLEAN)
                len += BOOLEAN_SIZE;
            else if (symbol.Type[1] == CHAR)
                len += CHAR_SIZE;
            for (vector<int>::iterator it = symbol.Degree.begin(); it != symbol.Degree.end(); it++)
            {
                len = len * *it;
            }
            Loc += len;
        }
        Table.insert(pair<string, SymbolTableNode>(name, symbol));
    }
    else
    {
        cout << "存在语法错误，自动退出程序" << endl;
        exit(1);
    }
}

void SymbolTable::getInfo()
{
    map<string, SymbolTableNode>::iterator it;
    map<string, SymbolTableNode>::iterator itEnd;
    it = Table.begin();
    itEnd = Table.end();
    cout << "=======================Table=======================" << endl;
    while (it != itEnd)
    {
        it->second.getInfo();
        it++;
    }
    cout << "=======================END=======================" << endl;
}

bool SymbolTable::find(string name)
{
    if (this->Table.find(name) != this->Table.end())
    {
        return true;
    }
    else
    {
        return false;
    }
}

#endif